<?php

namespace App\Services;

use App\Models\User;
use App\Models\Notification;
use App\Notifications\OrderStatusChanged;
use App\Notifications\AfterSalesStatusChanged;
use App\Notifications\AdminMessage;
use Illuminate\Support\Facades\Log;
use Illuminate\Pagination\LengthAwarePaginator;

class NotificationService
{
    /**
     * 发送订单状态变更通知
     */
    public function sendOrderStatusNotification(User $user, $order, string $oldStatus, string $newStatus): void
    {
        try {
            $user->notify(new OrderStatusChanged($order, $oldStatus, $newStatus));
            
            Log::info('Order status notification sent', [
                'user_id' => $user->id,
                'order_id' => $order->id,
                'order_number' => $order->order_number,
                'old_status' => $oldStatus,
                'new_status' => $newStatus,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to send order status notification', [
                'user_id' => $user->id,
                'order_id' => $order->id,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 发送售后状态变更通知
     */
    public function sendAfterSalesStatusNotification(User $user, $afterSales, string $oldStatus, string $newStatus): void
    {
        try {
            $user->notify(new AfterSalesStatusChanged($afterSales, $oldStatus, $newStatus));
            
            Log::info('After-sales status notification sent', [
                'user_id' => $user->id,
                'after_sales_id' => $afterSales->id,
                'old_status' => $oldStatus,
                'new_status' => $newStatus,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to send after-sales status notification', [
                'user_id' => $user->id,
                'after_sales_id' => $afterSales->id,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 发送管理员消息
     */
    public function sendAdminMessage(User $user, string $title, string $content, string $category = 'admin'): void
    {
        try {
            $user->notify(new AdminMessage($title, $content, $category));
            
            Log::info('Admin message sent', [
                'user_id' => $user->id,
                'title' => $title,
                'category' => $category,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to send admin message', [
                'user_id' => $user->id,
                'title' => $title,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 批量发送管理员消息
     */
    public function sendBulkAdminMessage(array $userIds, string $title, string $content, string $category = 'admin'): int
    {
        $successCount = 0;
        
        foreach ($userIds as $userId) {
            try {
                $user = User::find($userId);
                if ($user) {
                    $this->sendAdminMessage($user, $title, $content, $category);
                    $successCount++;
                }
            } catch (\Exception $e) {
                Log::error('Failed to send bulk admin message', [
                    'user_id' => $userId,
                    'title' => $title,
                    'error' => $e->getMessage(),
                ]);
            }
        }
        
        Log::info('Bulk admin message completed', [
            'total_users' => count($userIds),
            'success_count' => $successCount,
            'title' => $title,
        ]);
        
        return $successCount;
    }

    /**
     * 发送系统通知
     */
    public function sendSystemNotification(User $user, string $title, string $content, array $data = []): void
    {
        try {
            $user->notify(new AdminMessage($title, $content, 'system', $data));
            
            Log::info('System notification sent', [
                'user_id' => $user->id,
                'title' => $title,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to send system notification', [
                'user_id' => $user->id,
                'title' => $title,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * 获取用户通知列表
     */
    public function getUserNotifications(int $userId, array $filters = []): LengthAwarePaginator
    {
        $query = Notification::where('notifiable_id', $userId)
            ->where('notifiable_type', User::class);

        // 分类筛选
        if (!empty($filters['category'])) {
            $query->where('category', $filters['category']);
        }

        // 已读状态筛选
        if (isset($filters['read'])) {
            if ($filters['read']) {
                $query->whereNotNull('read_at');
            } else {
                $query->whereNull('read_at');
            }
        }

        // 关键词搜索
        if (!empty($filters['keyword'])) {
            $keyword = $filters['keyword'];
            $query->where(function ($q) use ($keyword) {
                $q->where('title', 'like', "%{$keyword}%")
                  ->orWhere('data', 'like', "%{$keyword}%");
            });
        }

        return $query->orderBy('created_at', 'desc')
            ->paginate($filters['per_page'] ?? 15)
            ->withQueryString();
    }

    /**
     * 获取用户未读通知数量
     */
    public function getUnreadCount(int $userId): int
    {
        return Notification::where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->whereNull('read_at')
            ->count();
    }

    /**
     * 获取用户最近通知
     */
    public function getRecentNotifications(int $userId, int $limit = 5): \Illuminate\Database\Eloquent\Collection
    {
        return Notification::where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->orderBy('created_at', 'desc')
            ->limit($limit)
            ->get();
    }

    /**
     * 标记通知为已读
     */
    public function markAsRead(int $notificationId, int $userId): bool
    {
        $notification = Notification::where('id', $notificationId)
            ->where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->first();

        if (!$notification) {
            return false;
        }

        if (!$notification->read_at) {
            $notification->update(['read_at' => now()]);
            
            Log::info('Notification marked as read', [
                'notification_id' => $notificationId,
                'user_id' => $userId,
            ]);
        }

        return true;
    }

    /**
     * 批量标记为已读
     */
    public function markMultipleAsRead(array $notificationIds, int $userId): int
    {
        $count = Notification::whereIn('id', $notificationIds)
            ->where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->whereNull('read_at')
            ->update(['read_at' => now()]);

        Log::info('Multiple notifications marked as read', [
            'notification_ids' => $notificationIds,
            'user_id' => $userId,
            'count' => $count,
        ]);

        return $count;
    }

    /**
     * 标记所有通知为已读
     */
    public function markAllAsRead(int $userId): int
    {
        $count = Notification::where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->whereNull('read_at')
            ->update(['read_at' => now()]);

        Log::info('All notifications marked as read', [
            'user_id' => $userId,
            'count' => $count,
        ]);

        return $count;
    }

    /**
     * 删除通知
     */
    public function deleteNotification(int $notificationId, int $userId): bool
    {
        $notification = Notification::where('id', $notificationId)
            ->where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->first();

        if (!$notification) {
            return false;
        }

        $notification->delete();
        
        Log::info('Notification deleted', [
            'notification_id' => $notificationId,
            'user_id' => $userId,
        ]);

        return true;
    }

    /**
     * 批量删除通知
     */
    public function deleteMultipleNotifications(array $notificationIds, int $userId): int
    {
        $count = Notification::whereIn('id', $notificationIds)
            ->where('notifiable_id', $userId)
            ->where('notifiable_type', User::class)
            ->delete();

        Log::info('Multiple notifications deleted', [
            'notification_ids' => $notificationIds,
            'user_id' => $userId,
            'count' => $count,
        ]);

        return $count;
    }

    /**
     * 清理过期通知
     */
    public function cleanupExpiredNotifications(int $days = 30): int
    {
        $count = Notification::where('created_at', '<', now()->subDays($days))
            ->whereNull('read_at')
            ->delete();

        Log::info('Expired notifications cleaned up', [
            'days' => $days,
            'count' => $count,
        ]);

        return $count;
    }

    /**
     * 获取通知统计
     */
    public function getNotificationStats(int $userId = null): array
    {
        $query = Notification::query();
        
        if ($userId) {
            $query->where('notifiable_id', $userId)
                  ->where('notifiable_type', User::class);
        }

        $total = $query->count();
        $unread = $query->whereNull('read_at')->count();
        $read = $total - $unread;

        // 按分类统计
        $byCategory = $query->selectRaw('category, COUNT(*) as count')
            ->groupBy('category')
            ->pluck('count', 'category')
            ->toArray();

        // 按类型统计
        $byType = $query->selectRaw('type, COUNT(*) as count')
            ->groupBy('type')
            ->pluck('count', 'type')
            ->toArray();

        return [
            'total' => $total,
            'unread' => $unread,
            'read' => $read,
            'by_category' => $byCategory,
            'by_type' => $byType,
        ];
    }

    /**
     * 发送测试通知
     */
    public function sendTestNotification(User $user, string $type = 'test'): void
    {
        $title = '测试通知';
        $content = '这是一条测试通知，用于验证通知系统是否正常工作。';
        
        switch ($type) {
            case 'order':
                $this->sendOrderStatusNotification($user, (object)['id' => 0, 'order_number' => 'TEST001'], 'pending', 'processing');
                break;
            case 'after_sales':
                $this->sendAfterSalesStatusNotification($user, (object)['id' => 0], 'pending', 'approved');
                break;
            case 'admin':
                $this->sendAdminMessage($user, $title, $content, 'admin');
                break;
            case 'system':
                $this->sendSystemNotification($user, $title, $content);
                break;
            default:
                $this->sendAdminMessage($user, $title, $content, 'test');
                break;
        }
    }

    /**
     * 获取通知模板
     */
    public function getNotificationTemplates(): array
    {
        return [
            'order_status_changed' => [
                'title' => '订单状态更新',
                'content' => '您的订单 {order_number} 状态已更新为：{status}',
                'variables' => ['order_number', 'status'],
            ],
            'after_sales_status_changed' => [
                'title' => '售后申请状态更新',
                'content' => '您的售后申请状态已更新为：{status}',
                'variables' => ['status'],
            ],
            'admin_message' => [
                'title' => '系统消息',
                'content' => '{content}',
                'variables' => ['content'],
            ],
            'system_maintenance' => [
                'title' => '系统维护通知',
                'content' => '系统将于 {start_time} 至 {end_time} 进行维护，期间可能影响正常使用。',
                'variables' => ['start_time', 'end_time'],
            ],
        ];
    }
}
